package cn.batch.daemon.loadBatch;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.batch.daemon.Configuration;
import cn.batch.daemon.bean.TaskMissionBean;
import cn.batch.daemon.jdbc.JdbcConnectionOracleProvider;
import cn.batch.daemon.jdbc.MessionTaskStore;
import cn.batch.daemon.procWebservice.bean.HtmlParseListRequest;
import cn.batch.daemon.procWebservice.bean.HtmlParseRequest;
import cn.batch.daemon.procWebservice.bean.HtmlParseResponse;
import cn.batch.daemon.procWebservice.client.HtmlParseHandlerBatchService_Client;
import cn.batch.daemon.taskEnum.MissionSts;
import cn.batch.daemon.taskEnum.TaskMissionType;
import cn.batch.daemon.util.JdbcUtils;

import com.skyon.core.config.BaseJNDIEnv;
import com.skyon.core.jdbc.ConnectionProvider;

/**
 * 我的南京公积金网贷贷后发送客户信息到人行。
 * @author MyUser
 */
public class RiskWarnMonthWDGJJSendInfo {
	private static final Log logger = LogFactory.getLog(RiskWarnMonthWDGJJSendInfo.class);

	private static final String BANKCODE = "0120";
	private static ConnectionProvider connectionProvider;

	private static final String DEFAULT_BATCH_SIZE = "riskWarning.batch.size"; // 默认每个批次发送客户的数量
	private int batchSize; // 批次大小

	private String batchDate;
	private Configuration config;

	public static void init() {
		BaseJNDIEnv.init();
		connectionProvider = new JdbcConnectionOracleProvider();
	}

	/**
	 * @param config
	 */
	public RiskWarnMonthWDGJJSendInfo(Configuration config) {
		super();
		this.config = config;
	}

	/**
	 * 风险预警(按月)批量处理--从 BATCH_RISK_DATA 表中获得需要查询人行征信数据的客户信息
	 * 
	 * @return List
	 * @throws SQLException
	 * @throws Exception
	 */
	public static List<HtmlParseRequest> getRiskMonthData(String flagDate)
			throws SQLException {
		init();
		Connection connection = null;
		Statement statement = null;
		ResultSet rs = null;

		List<HtmlParseRequest> requestVoList = new ArrayList<HtmlParseRequest>();
		// 风险预警客户信息(证件号、证件类型、客户姓名)按月
		String sql = "select t1.paperid, (case when t1.paperkind in ('1','k') then '0' end) paperkind, t1.custname "
				     + "from t_psl_risk_gjjwd t1 "
				     + "where not exists (select * from pboc_summary t2 "
				            + "where trunc(to_date(t2.querytime, 'yyyy.mm.dd hh24:mi:ss')) >= trunc(add_months(sysdate, '-1')) "
				              + "and t2.name = t1.custname "
				              + "and t2.certno = t1.paperid)";
		logger.debug("筛选查询需要查询人行征信数据的客户信息SQL:  " + sql);
		try {
			connection = connectionProvider.getConnection();
			statement = connection.createStatement();
			rs = statement.executeQuery(sql);
			while (rs.next()) {
				HtmlParseRequest parseRequest = new HtmlParseRequest();
				parseRequest.setBANKCODE(BANKCODE);
				parseRequest.setTRANDATE(flagDate);
				SimpleDateFormat df = new SimpleDateFormat("HHmmssSSS");
				parseRequest.setTRANTIME(df.format(new Date()));

				// 证件号码
				if (rs.getString(1) != null) {
					parseRequest.setQuerierCertno(rs.getString(1).trim());
				}
				// 证件类型
				if (rs.getString(2) != null) {
					parseRequest.setQuerierCertype(rs.getString(2).trim());
				}
				// 客户姓名
				if (rs.getString(3) != null) {
					parseRequest.setQuerierName(rs.getString(3).trim());
				}
				requestVoList.add(parseRequest);
			}
		} catch (SQLException e) {
			logger.error("筛选查询需要查询人行征信数据的客户信息出错 QUERY SQL:" + sql, e);
			e.printStackTrace();
			throw e;
		} finally {
			JdbcUtils.closeResultSet(rs);
			JdbcUtils.closeStatement(statement);
			JdbcUtils.closeConnection(connection);
		}
		return requestVoList;
	}

	public void run() {

		TaskMissionBean tmb = new TaskMissionBean();
		try {
			// 记录操作
			logger.info("*******************开始调用风险预警(按月)人行征信数据检核规则***********************");
			tmb.setBatch_no(batchDate); // 批次号
			tmb.setMissionTyp(TaskMissionType.WDGJJ); // 任务类型
			tmb.setDisposeStartTm(new Timestamp(System.currentTimeMillis())); // 起始时间
			tmb.setMissionSts(MissionSts.DISPOSING); // 任务状态 执行中
			tmb.setRemark("开始筛查公积金网贷我的南京风险预警(按月)，需要更新人行征信数据记录。"); // 备注
			MessionTaskStore.updateTaskMissionStatus(tmb);
			List<HtmlParseRequest> requestVoList = RiskWarnMonthWDGJJSendInfo.getRiskMonthData(batchDate);
			logger.info("发送客户详情如下：");
			logger.info(requestVoList);
			logger.info("开始执行公积金网贷我的南京风险预警(按月)客户征信数据检核及查询发送批处理任务，批次日期为" + batchDate);
			batchSize = config.getSetting(DEFAULT_BATCH_SIZE, 1000);
			// 分批发送给人行
			int requestVoSize = requestVoList.size();
			int batchNum = requestVoSize / batchSize;
			int lastBatchNum = requestVoSize % batchSize;
			if (lastBatchNum > 0) {
				batchNum++;
			}

			if (requestVoSize > 0) {
				logger.info("开始调用人行征信接口，发送数据。");
				// 记录日志到数据库
				tmb.setDisposeStartTm(new Timestamp(System.currentTimeMillis())); // 起始时间
				tmb.setMissionSts(MissionSts.DISPOSING); // 任务状态 执行中
				tmb.setRemark("开始调用人行征信接口，发送数据。"); // 备注
				MessionTaskStore.updateTaskMissionStatus(tmb);

				HtmlParseListRequest listRequest = new HtmlParseListRequest();
				List<HtmlParseRequest> tempList = null;
				int fromIndex, toIndex, successNum = 0, actualBatchSize;
				long startTimeMillis;
				for (int i = 0; i < batchNum; i++) {
					fromIndex = i * batchSize;
					toIndex = (i == batchNum - 1) ? fromIndex + lastBatchNum : fromIndex + batchSize;
					tempList = requestVoList.subList(fromIndex, toIndex);
					listRequest.setHtmlParseRequestList(tempList);
					HtmlParseResponse response = null;
					actualBatchSize = tempList.size();
					logger.info(new StringBuilder(90).append("正在发送批次  ")
							.append(i + 1).append("  ，客户数量   ")
							.append(actualBatchSize).append("  ; 总批次数  ")
							.append(batchNum).append("  ，总客户数  ")
							.append(requestVoSize));
					// 调用人行征信接口,传递客户数据,并获得响应
					startTimeMillis = System.currentTimeMillis();
					response = HtmlParseHandlerBatchService_Client.getProcResult(listRequest);
					logger.debug("调用耗时：" + ((System.currentTimeMillis() - startTimeMillis) / 1000) + "秒");
					
					/*
					 * 1//成功 2//失败 3//请求记录错误 4//请求记录重复 5//查询失败 6//解析失败 7//处理异常
					 * 8//接收成功待处理 9//请求报文处理中 a//成功生成反馈报文 X//查无此人
					 */
					if (response == null || !"8".equals(response.getResultCode())) {
						logger.warn("调用人行征信接口返回失败结果：" + response.toString());
					} else {
						successNum += actualBatchSize;
						logger.info("批次  " + (i + 1) + "  发送成功。");
					}

				} // for end
				StringBuilder remark = new StringBuilder(100)
						.append("结束调用人行征信接口，发送完成。累计成功发送客户数  ")
						.append(successNum).append("  总客户数  ")
						.append(requestVoSize);
				logger.info(remark.toString());

				// 记录日志到数据库
				tmb.setDisposeEndTm(new Timestamp(System.currentTimeMillis()));
				tmb.setMissionSts(MissionSts.SUCCESS); // 任务状态
				tmb.setRemark(remark.toString()); // 备注
				MessionTaskStore.updateTaskMissionStatus(tmb);
			}
		} catch (Exception e) {
			tmb.setMissionSts(MissionSts.FAILED);
			tmb.setDisposeEndTm(new Timestamp(System.currentTimeMillis()));
			tmb.setRemark("公积金网贷我的南京风险预警(按月)获得客户信息或连接人行征信前置系统时失败,请联系系统管理员解决问题。");
			try {
				MessionTaskStore.updateTaskMissionStatus(tmb);
			} catch (SQLException sqle) {
				logger.error("公积金网贷我的南京风险预警(按月)更新任务状态信息表失败。", sqle);
			}
			logger.error("公积金网贷我的南京风险预警(按月)批量处理失败", e);
			throw new RuntimeException(e);
		}
	}
	/**
	 * @param batchDate
	 *            the batchDate to set
	 */
	public void setBatchDate(String batchDate) {
		this.batchDate = batchDate;
	}
}
